package com.glsc.ngateway.opmanage.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.api.common.enums.PageConstant;
import com.glsc.ngateway.common.api.common.enums.PlatformConstant;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.it.ItDict;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.it.ItDictData;
import com.glsc.ngateway.common.api.platform.resp.PlatformResponse;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.it.ItApplicationDetailRepo;
import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.opmanage.aspect.UserCache;
import com.glsc.ngateway.opmanage.service.DictionaryService;
import com.glsc.ngateway.opmanage.utils.JsonTool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/it/dictionary")
@Api(value = "字典管理", tags = {"字典管理"})
public class DictionaryController {

    // private static Logger logger = Logger.getLogger(ProjectManage.class);
    private static final Logger logger = LoggerFactory.getLogger(DictionaryController.class);

    public static final int MEMBER_READ_ONLY = 0;
    public static final int MEMBER_PROJECT_LEADER = 1;

    @Autowired
    private DictionaryService dictionaryService;
//    @Autowired
//    private OperationService operationService;
//    @Autowired
//    private CloudService cloudService;
//    @Autowired
//    private ServerService serverService;
    @Autowired
    private ItApplicationDetailRepo itApplicationDetailRepo;

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private UserCache userCache;

    /**
     * 根据条件查询字典分页
     * @param dictName
     * @param dictData
     * @param pageNo
     * @param pageSize
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "listpage")
    @ApiOperation(value = "查询字典项分页列表", notes = "查询字典项分页列表")
    public PlatformResponse<Page<ItDictData>> findListPage(
            @ApiParam(required = false, value = "字典名字，支持模糊搜索") @RequestParam(required = false) String dictName,
            @ApiParam(required = false, value = "字典编码，支持模糊搜索") @RequestParam(required = false) String dictData,
            @ApiParam(required = false, value = "页码1开始") @RequestParam(required = false) Integer pageNo,
            @ApiParam(required = false, value = "每页显示条数 默认10") @RequestParam(required = false) Integer pageSize) {

        Map<String, Object> param = new HashMap<>();
        pageNo = PageUtil.initPageNo(pageNo);
        pageSize = PageUtil.initPageSize(pageSize);

        param.put("GT_dictId", 0);
        if (StrUtil.isNotEmpty(dictName)) {
            param.put("LIKE_dictName", dictName);
        }
        if (StrUtil.isNotEmpty(dictData)) {
            param.put("LIKE_dictData", dictData);
        }

        Page<ItDictData> pageData = dictionaryService.findPage(pageNo, pageSize, param);
        List<ItDictData> dataList = pageData.getContent();
        if(dataList.size()>0){
            for(ItDictData m: dataList){
                if(null!=m.getParentCode() && m.getParentCode().length() > 0){
                    //某个字典有parentCode时，通过parentCode查到父级字典的dictValues数组，然后把它封装进该字典对象中，方便前端配置父子关联关系
                    ItDictData byParentCode = dictionaryService.findByDictData(m.getParentCode());
                    if(null!=byParentCode){
                        List<ItDict> parentDictValues = byParentCode.getDictValues();
                        m.setParentDictValues(parentDictValues);

                    }
                }
            }
        }
        return PlatformResponse.successData(pageData);
    }


    /**
     * 根据dictData查询字典全部。不分页
     */
    @GetMapping("/queryByDictData")
    @ApiOperation(value = "根据字典编码查询", notes = "根据字典编码查询")
    public PlatformResponse<ItDictData> findByCode(
            @ApiParam(required = true, value = "字典项编码") @RequestParam String dictData,
            @ApiParam(required = false, value = "父级字典项值") @RequestParam(required = false) String parentValue
    ) {
        try {
            ItDictData byDictData = dictionaryService.findByDictData(dictData);
            if (byDictData != null) {
                if(parentValue!=null && parentValue.length() > 0){
                    List<ItDict> filterDictValues = byDictData.getDictValues().stream().filter(item -> item.getParentValue().equals(parentValue)).collect(Collectors.toList());
                    byDictData.setDictValues(filterDictValues);
                }
                return PlatformResponse.successData(byDictData);
            } else {
                return PlatformResponse.successData(new ItDictData());
            }
        } catch (Exception e) {
            logger.error("Error", e);
            return PlatformResponse.failedMsg(e.getMessage());
        }

    }


    //新增或修改字典
    @PostMapping("/addOrUpdate")
    @ApiOperation(value = "新增或修改字典", notes = "新增或修改字典")
    public PlatformResponse<Void> addOrUpdate(@ApiParam(required = true, value = "字典对象") @RequestBody ItDictData itDictData) {
        String dictName = itDictData.getDictName();
        String dictData = itDictData.getDictData();
        String msg = "创建成功";
        if (itDictData.getDictId() != null) {
            msg = "修改成功";
        }
        if (dictName == null || dictName.length() == 0) {
            return PlatformResponse.failedMsg("字典名称不能为空");
        }
        if (dictData == null || dictData.length() == 0) {
            return PlatformResponse.failedMsg("字典代码不能为空");
        }
        ItDictData byDictName = dictionaryService.findByDictName(dictName);
        if (byDictName != null && !byDictName.getDictId().equals(itDictData.getDictId())) {
            return PlatformResponse.failedMsg("字典名称已存在，不能重复添加");
        }
        ItDictData byDictData = dictionaryService.findByDictData(dictData);
        if (byDictData != null && !byDictData.getDictId().equals(itDictData.getDictId())) {
            return PlatformResponse.failedMsg("字典代码已存在，不能重复添加");
        }
        //先修改字典子项
        List<ItDict> dictValues = itDictData.getDictValues();
        //判断字典子项的key是否重复，如果重复则报错
        HashSet<String> sites = new HashSet();
        if (null != dictValues && dictValues.size() > 0) {
            ArrayList<ItDict> itDictList = new ArrayList<>();
            for (ItDict itDict : dictValues) {
                if (sites.contains(itDict.getDictSubentry())) {
                    return PlatformResponse.failedMsg("字典项值不能重复！");
                }
                sites.add(itDict.getDictSubentry());
                itDictList.add(dictionaryService.saveDictValues(itDict));
            }
            itDictData.setDictValues(itDictList);
        }
        dictionaryService.save(itDictData);
        return PlatformResponse.successMsg(msg);
    }

    //逻辑删除字典
    @PostMapping("/delete")
    @ApiOperation(value = "删除字典", notes = "删除字典")
    public PlatformResponse<Void> delete(@RequestBody String jsonId) {
        Integer dictId = JsonTool.parseJsonIdStr(jsonId);
        ItDictData byId = dictionaryService.findById(dictId);
        if (null != byId) {
            dictionaryService.delete(byId);
            return PlatformResponse.successMsg("删除成功！");
        } else {
            return PlatformResponse.failedMsg("删除失败，字典ID不存在！");
        }
    }

    //===================================================以下是旧API=====================================

    //根据dictData查询 IT业务所有字典 改造后废弃
    @Deprecated
    @RequestMapping(method = RequestMethod.GET, value = "queryDictList")
    @ApiOperation(value = "字典列表", notes = "字典列表")
    public PlatformResponse<Page<ItDict>> queryDictList(
            @ApiParam(value = "页码从1开始") @RequestParam(required = false) Integer pageNo,
            @ApiParam(value = "每页显示条数 默认10") @RequestParam(required = false) Integer pageSize, @RequestParam(required = false) String dictData) {
        if (pageNo == null) {
            pageNo = 1;
        }
        if (pageSize == null) {
            pageSize = PageConstant.PageSize;
        }
        if (StringUtils.isEmpty(dictData)) {
            return PlatformResponse.failedMsg("queryDictList参数为空");
        }

        List<ItDict> dictList;
        switch (dictData) {
//            case "业务系统":
//                dictList = dictionaryService.pageByTypeAdapter(operationService.queryAllOperation(), o -> ItDict.builder().dictSubentry(o.getOpId()).dictValue(o.getOpName()).build());
//                break;
            case "应用名称":
                dictList = dictionaryService.pageByTypeAdapter(itApplicationDetailRepo.findAll(), o -> ItDict.builder().dictSubentry(o.getMxId()).dictValue(o.getMxName()).build());
                break;
//            case "区域":
//                dictList = dictionaryService.pageByTypeAdapter(cloudService.queryCloudAreaList(), o -> ItDict.builder().zdId(o.getListId()).dictSubentry(String.valueOf(o.getListId())).dictValue(o.getListName()).build());
//                break;
//            case "虚拟机IP":
//                dictList = dictionaryService.pageByTypeAdapter(serverService.queryAllServer(), o -> ItDict.builder().zdId(o.getDevId()).dictSubentry(String.valueOf(o.getDevId())).dictValue(o.getIp1()).build());
//                break;
            case "业务类型":
                dictList = dictionaryService.pageByTypeAdapter(new ArrayList<>(PlatformConstant.itSystemType.keySet()), o -> ItDict.builder().zdId(o).dictValue(PlatformConstant.itSystemType.get(o)).build());
                break;
            case "建设方式":
                dictList = dictionaryService.pageByTypeAdapter(new ArrayList<>(PlatformConstant.itBuildType.keySet()), o -> ItDict.builder().zdId(o).dictValue(PlatformConstant.itBuildType.get(o)).build());
                break;
            case "在建状态":
                dictList = dictionaryService.pageByTypeAdapter(new ArrayList<>(PlatformConstant.itBuildStatus.keySet()), o -> ItDict.builder().zdId(o).dictValue(PlatformConstant.itBuildStatus.get(o)).build());
                break;
            case "标记":
                dictList = dictionaryService.pageByTypeAdapter(new ArrayList<>(PlatformConstant.itMark.keySet()), o -> ItDict.builder().zdId(o).dictValue(PlatformConstant.itMark.get(o)).build());
                break;
            case "虚拟机环境":
                dictList = dictionaryService.pageByTypeAdapter(new ArrayList<>(PlatformConstant.itVirtualRunEnviron.keySet()), o -> ItDict.builder().zdId(o).dictValue(PlatformConstant.itVirtualRunEnviron.get(o)).build());
                break;
            case "群集":
                dictList = dictionaryService.pageByTypeAdapter(new ArrayList<>(PlatformConstant.itQj.keySet()), o -> ItDict.builder().zdId(o).dictValue(PlatformConstant.itQj.get(o)).build());
                break;
            case "单双电源":
                dictList = dictionaryService.pageByTypeAdapter(new ArrayList<>(PlatformConstant.itBattery.keySet()), o -> ItDict.builder().zdId(o).dictValue(PlatformConstant.itBattery.get(o)).build());
                break;
            case "云平台":
                dictList = dictionaryService.pageByTypeAdapter(new ArrayList<>(PlatformConstant.itCloudPlatform.keySet()), o -> ItDict.builder().zdId(o).dictValue(PlatformConstant.itCloudPlatform.get(o)).build());
                break;
            case "系统变更类型":
                dictList = dictionaryService.pageByTypeAdapter(new ArrayList<>(PlatformConstant.systemChangeType.keySet()), o -> ItDict.builder().zdId(o).dictValue(PlatformConstant.systemChangeType.get(o)).build());
                break;
            default:
                dictList = dictionaryService.queryDictList(pageNo, pageSize, dictData).get().map(dict -> {
                    if (dict.getDictKey() != null) {
                        dict.setZdId(-1 == dict.getDictKey() ? null : dict.getDictKey());
                    }
                    return dict;
                }).collect(Collectors.toList());
        }
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize);
        Page<ItDict> result = new PageImpl<>(dictList, pageable, dictList.size());
        return PlatformResponse.successData(result);
    }

    /**
     * 提交或修改字典
     */
    @Deprecated
    @RequestMapping(method = RequestMethod.POST, value = "addOrUpdateDict")
    @ApiOperation(value = "提交或修改字典", notes = "提交或修改字典")
    public PlatformResponse<Void> addOrUpdateDict(@RequestBody ItDict itDict) {
        dictionaryService.addOrUpdateDict(itDict);
        return PlatformResponse.successMsg("创建或修改成功");
    }

    /**
     * 删除字典
     */
    @Deprecated
    @RequestMapping(method = RequestMethod.POST, value = "deleteDict")
    @ApiOperation(value = "删除字典", notes = "删除字典")
    public PlatformResponse<Void> deleteDict(@RequestBody String zdId) {
        JSONObject jsonObject = (JSONObject) JSON.parse(zdId);
        String id = jsonObject.getString("zdId");
        if (StringUtils.isNotEmpty(id)) {
            dictionaryService.deleteDict(id);
        }
        return PlatformResponse.successMsg("删除字典成功");
    }

    // 查询所有字典类型，不带条件（前端未调用）
//    @RequestMapping(method = RequestMethod.GET, value = "queryDictDataList")
//    @ApiOperation(value = "查询所有字典类型", notes = "查询所有字典类型")
//    public PlatformResponse queryDictDataList(
//            @ApiParam(value="页码从1开始") @RequestParam(required = false) Integer pageNo,
//            @ApiParam(value="每页显示条数 默认10") @RequestParam(required = false) Integer pageSize
//    ) {
//        if(pageNo == null){
//            pageNo =1;
//        }
//        if(pageSize == null){
//            pageSize = PageConstant.PageSize;
//        }
//
//        List<ItDictData> result = dictionaryService.queryAllDictData();
//        PlatformResponse ret = PlatformResponse.instanceOfSuccss();
//        ret.setData(result);
//        return ret;
//    }
}